﻿using CommunicationLib;
using CommunicationLib.Model;
using PlcLib.Enums;
using PlcLib.Interface;
using PlcLib.Model;
using System;
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Runtime.Remoting.Messaging;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;
using CommunicationLib.Helper; // 修改：添加JsonConvert的using指令

namespace PlcLib
{
    public partial class OrmonPlc : Base.PlcBase
    {
        private Net net;//PLC网络参数
        public override event Action<object, PlcEventArgs> OnMessage;//PLC消息事件
        public override event Action<object, PlcEventArgs> OnError;//PLC错误事件
        public override event Action<object, DataPackage> OnSend;//PLC发送数据事件
        public override event Action<object, DataPackage> OnReceived;//PLC接收数据事件

        public override void Initialize(Net net)
        {
           this.net = net; // Store the net parameter in the class variable
           communication.Initialize(IPAddress.Parse(net.Ip), net.LocalPort);//初始化通信
            Init();
        }

        public override void Initialize(Port port)
        {
            communication.Initialize(port.ComName, port.BaudRate);
            Init();
        }

        private void Init()
        {
            connectedState = ConnectedState.连接中;
            OnMessage?.Invoke(this, new PlcEventArgs { Message = "开始连接" });
            
            bool connectResult = false;
            int maxRetries = 3; // 减少重试次数，避免长时间等待
            
            for (int i = 0; i < maxRetries; i++)
            {
                try
                {
                    connectResult = Connect();
                    if (connectResult)
                    {
                        connectedState = ConnectedState.连接成功;
                        OnMessage?.Invoke(this, new PlcEventArgs { Message = "连接成功" });
                        break;
                    }
                    else
                    {
                        OnError?.Invoke(this, new PlcEventArgs { Message = $"连接失败，正在尝试第{i + 1}次重连" });
                        Thread.Sleep(1000);
                    }
                }
                catch (Exception ex)
                {
                    OnError?.Invoke(this, new PlcEventArgs { Message = $"连接异常：{ex.Message}", Exception = ex });
                    Thread.Sleep(1000);
                }
            }
            
            if (!connectResult)
            {
                connectedState = ConnectedState.连接失败;
                OnError?.Invoke(this, new PlcEventArgs { Message = "连接失败，请检查网络或PLC状态" });
                return;
            }
            
            // 修改：连接成功后直接标记为连接成功，不要立即设置为通讯正常
            // connectedState = ConnectedState.通讯正常; // 删除这行
            OnMessage?.Invoke(this, new PlcEventArgs { Message = "PLC初始化完成，等待启动通讯" });
        }

        private bool Connect()
        {
            bool result = false;
           
            try
            {
                ConnectionResult connect = communication.Connect();
                if (connect.Success)
                {
                    OnMessage?.Invoke(this, new PlcEventArgs { Message = "TCP连接成功" });
                   
                    connectedState = ConnectedState.连接成功;
                    
                    // 握手操作
                    bool shakeHandsResult = ShakeHands();
                    if (shakeHandsResult)
                    {
                        // 关键修改：握手成功后明确设置状态
                        connectedState = ConnectedState.握手成功;
                        OnMessage?.Invoke(this, new PlcEventArgs { Message = "握手成功，连接完全建立" });
                        result = true;
                    }
                    else
                    {
                        connectedState = ConnectedState.握手失败;
                        OnError?.Invoke(this, new PlcEventArgs { Message = "握手失败" });
                        result = false;
                    }
                }
                else
                {
                    OnError?.Invoke(this, new PlcEventArgs { Message = "TCP连接失败" });
                    result = false;
                    connectedState = ConnectedState.连接失败;
                }
            }
            catch (Exception ex)
            {
                OnError?.Invoke(this, new PlcEventArgs { Message = "连接异常", Exception = ex });
                result = false;
                connectedState = ConnectedState.连接失败;
            }

            return result;
        }
        /// <summary>
        /// 与欧姆龙下位机PLC握手操作
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>

        private bool ShakeHands()
        {   
            bool result = false;
            try
            {
                var lastNode = net.LocaliPAddress.GetAddressBytes().Last();
                var finsBytes = ByteHelper.GetShakeBytes(lastNode);
                var shakeResult = communication.ShakeHands(finsBytes);
                OnSend?.Invoke(this, new DataPackage 
                { 
                    CommandId = commandId++, 
                    SendBuffer = finsBytes, 
                    SendTime = DateTime.Now 
                });

                if(shakeResult.Success == false)
                {
                    OnError?.Invoke(this, new PlcEventArgs { Message = "握手请求发送失败" });
                    return false; // 握手失败
                }

                // 修复：握手成功后设置result为true
                result = true;
                OnMessage?.Invoke(this, new PlcEventArgs { Message = "握手成功" });
                
                // 可选：如果需要验证握手响应数据，可以添加这部分代码
                byte[] receiveBytes = shakeResult.Content as byte[] ?? new byte[0];
                if (receiveBytes.Length > 0)
                {
                    OnReceived?.Invoke(this, new DataPackage 
                    { 
                        ReceiveBuffer = receiveBytes, 
                        ReceiveTime = DateTime.Now, 
                        CommandId = 0 
                    });
                    OnMessage?.Invoke(this, new PlcEventArgs { Message = $"握手响应长度: {receiveBytes.Length}" });
                }
            }
            catch (Exception ex)
            {
                OnError?.Invoke(this, new PlcEventArgs { Message = $"握手过程异常: {ex.Message}", Exception = ex });
                result = false;
            }
            
            return result;
        }
        public override IPlcResult Start(Action action = null)
        {
            IPlcResult plcResult = new OrmonResult();
            
            try
            {
                // 修改：检查更广泛的成功状态
                if (connectedState == ConnectedState.通讯正常 || 
                    connectedState == ConnectedState.连接成功 || 
                    connectedState == ConnectedState.握手成功)
                {
                    plcResult.Message = $"初始化完成，当前状态：{connectedState}";
                    plcResult.Sucess = true;
                    OnMessage?.Invoke(this, new PlcEventArgs { Message = plcResult.Message });
                }
                else
                {
                    plcResult.Message = $"未完成初始化，当前状态：{connectedState}";
                    plcResult.Sucess = false;
                    OnError?.Invoke(this, new PlcEventArgs { Message = plcResult.Message });
                    return plcResult;
                }
                
                // 订阅通讯事件
                communication.OnReceived -= Communication_OnReceived; // 先取消订阅，避免重复
                communication.OnError -= Communication_OnError;
                
                communication.OnReceived += Communication_OnReceived;
                communication.OnError += Communication_OnError;
                
                // 启动通讯
                var result = communication.Start();
                if (!result)
                {
                    plcResult.Sucess = false;
                    plcResult.Message = "PLC通信启动失败";
                    OnError?.Invoke(this, new PlcEventArgs { Message = plcResult.Message });
                    return plcResult;
                }

                // 修改：延迟启动发送线程，确保通讯完全准备好
                Task.Delay(500).ContinueWith(_ => 
                {
                    try
                    {
                        Task.Factory.StartNew(SendThread, TaskCreationOptions.LongRunning);
                        OnMessage?.Invoke(this, new PlcEventArgs { Message = "SendThread 已启动" });
                    }
                    catch (Exception ex)
                    {
                        OnError?.Invoke(this, new PlcEventArgs { 
                            Message = $"启动SendThread失败: {ex.Message}", 
                            Exception = ex 
                        });
                    }
                });
                
                // 设置为通讯正常
                connectedState = ConnectedState.通讯正常;
                
                plcResult.Sucess = true;
                plcResult.Message = "PLC通信启动成功";
                OnMessage?.Invoke(this, new PlcEventArgs { Message = plcResult.Message });
                
                // 添加诊断信息输出
                DiagnosticCheck(); // 在启动成功后立即进行诊断检查
            }
            catch (Exception ex)
            {
                plcResult.Sucess = false;
                plcResult.Message = $"启动过程异常: {ex.Message}";
                OnError?.Invoke(this, new PlcEventArgs { Message = plcResult.Message, Exception = ex });
            }

            return plcResult;
        }
        private void Communication_OnError(object arg1, CommunicationArgsBase arg2)
        {
            OnError?.Invoke(this, new PlcEventArgs { Message = "通信错误", Exception = arg2.Exception });
        }

        //接收通讯处数据的回调函数
        private void Communication_OnReceived(object arg1, DataPackage package)
        {
            OnMessage?.Invoke(this, new PlcEventArgs { 
                Message = $"Communication_OnReceived：接收到数据，原CommandId={package.CommandId}, 数据长度={package.ReceiveBuffer?.Length ?? 0}" 
            });

            // 不要修改CommandId，使用原始的package
            lock (receiveLocker)
            {
                receivePackages.Add(package);
                OnMessage?.Invoke(this, new PlcEventArgs { 
                    Message = $"数据包已加入队列：CommandId={package.CommandId}, 当前队列数量={receivePackages.Count}" 
                });
            }
            
            OnReceived?.Invoke(this, package);
            sendWaiter.Set();
        }
        public override IPlcResult Send(byte[] array)
        {
            OrmonResult plcResult = new OrmonResult();
            var package = new DataPackage
            {
                NeedLength = -1// 需要的长度，-1表示不按照长度获取下位机回复
            };
            package.CommandId = GetCommandId(); // 设置命令ID
            package.SendBuffer = array;
            Enqueue(package);
            //等待回复
            Stopwatch stopwatch = Stopwatch.StartNew();
            DataPackage receivedPackage = default;
            bool found = false;
            while (stopwatch.ElapsedMilliseconds < net.MaxMilliseconds)// 如果超过最大等待时间则超时
            {
                lock (receiveLocker)
                {
                    var foundPackage = receivePackages.Find(p => p.CommandId == package.CommandId);
                    if (foundPackage.CommandId != 0)
                    {
                        receivedPackage = foundPackage;
                        receivePackages.Remove(foundPackage);
                        found = true;
                        break;
                    }
                }
               Thread.Sleep(1);
            }
            if (found)
            {
                CombineResult(plcResult, package, receivedPackage);
            }
            else
            {
                plcResult.Sucess = false;
                plcResult.Message = "发送超时，未收到PLC响应";
                OnError?.Invoke(this, new PlcEventArgs { Message = plcResult.Message });
            }

            return plcResult;
        }
        public override Task<IPlcResult> SendAsync(byte[] array)
        {
            return Task.Run(() =>
            {
                return Send(array);
            });
        }
        // 将 Read 方法中的 package.NeedLength = GetNeedLength<T>(command.Length); 修改为 package.NeedLength = 30 + command.Length * 2;
        // 因为此处没有泛型类型参数 T，直接用 int 计算长度即可。

        public override IPlcResult Read(Command command)
        {
            IPlcResult result = new OrmonResult
            {
                Command = command
            };

            DataPackage package = new DataPackage();
            package.NeedLength = 30 + command.Length * 2; // 修正：直接计算需要的长度
            package.CommandId = GetCommandId(); // 设置命令ID
            package.SendBuffer = command.GetReadBuffer(this.net, package.CommandId);

            // 调试信息：记录发送的CommandId
            OnMessage?.Invoke(this, new PlcEventArgs
            {
                Message = $"Read方法：准备发送CommandId={package.CommandId}"
            });

            Enqueue(package);

            // 等待SendThread处理发送
            Thread.Sleep(200); // 给SendThread更多时间来发送数据

            Stopwatch stopwatch = Stopwatch.StartNew();
            DataPackage receivedPackage = default;
            bool found = false;
            int checkCount = 0;

            while (stopwatch.ElapsedMilliseconds < net.MaxMilliseconds)
            {
                lock (receiveLocker)
                {
                    // 调试：定期输出当前接收队列状态
                    if (checkCount % 50 == 0)
                    {
                        var queueIds = receivePackages.Select(p => p.CommandId.ToString()).ToArray();
                        OnMessage?.Invoke(this, new PlcEventArgs
                        {
                            Message = $"Read等待中：寻找CommandId={package.CommandId}, 当前队列=[{string.Join(",", queueIds)}], 耗时={stopwatch.ElapsedMilliseconds}ms"
                        });
                    }

                    var foundPackage = receivePackages.Find(p => p.CommandId == package.CommandId);
                    if (foundPackage.CommandId != 0)
                    {
                        receivedPackage = foundPackage;
                        receivePackages.Remove(foundPackage);
                        found = true;
                        OnMessage?.Invoke(this, new PlcEventArgs
                        {
                            Message = $"Read成功：找到CommandId={package.CommandId}, 用时={stopwatch.ElapsedMilliseconds}ms"
                        });
                        break;
                    }
                }

                Thread.Sleep(10);
                checkCount++;
            }

            if (found)
            {
                CombineResult(result, package, receivedPackage);
            }
            else
            {
                result.Sucess = false;
                result.Message = "读取超时，未收到PLC响应";

                // 超时时输出详细诊断信息
                lock (receiveLocker)
                {
                    var queueIds = receivePackages.Select(p => p.CommandId.ToString()).ToArray();
                    OnError?.Invoke(this, new PlcEventArgs
                    {
                        Message = $"Read超时：CommandId={package.CommandId}, 超时={stopwatch.ElapsedMilliseconds}ms, 队列=[{string.Join(",", queueIds)}]"
                    });
                }
            }
            WriteLog(command, package, result);
            return result;
        }

        

        /// <summary>
        /// 入队 生产者（产生待发送的数据包）
        /// </summary>
        /// <param name="package"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        private object Enqueue(DataPackage package)
        {
            lock (sendLocker)
            {
                sendPackages.Enqueue(package);//将数据包添加到发送队列，缓冲队列（连接生产者和消费者）
            } return null;
        }

        public override async Task<IPlcResult> ReadAsync(Command command)
        {
            return await Task.Run(() =>
            {

                return Read(command); // 直接调用同步版本
            });
        }

        /// <summary>
        /// 消费者线程（消费队列中的数据包）
        /// </summary>
        private void SendThread()
        {
            OnMessage?.Invoke(this, new PlcEventArgs { Message = "SendThread 启动成功" });
            
            try
            {
                while (!cancellationTokenSource.IsCancellationRequested)
                {
                    try
                    {
                        DataPackage package;
                        bool hasPackage = false;
                        
                        // 检查是否有待发送的数据包
                        lock (sendLocker)
                        {
                            if (sendPackages.Count > 0)
                            {
                                package = sendPackages.Dequeue();
                                hasPackage = true;
                            }
                            else
                            {
                                package = default;
                            }
                        }
                        
                        if (!hasPackage)
                        {
                            // 修改：使用简单的Thread.Sleep替代WaitOne
                            Thread.Sleep(100);
                            continue;
                        }
                        
                        // 处理数据包发送
                        ProcessDataPackage(package);
                    }
                    catch (Exception innerEx)
                    {
                        OnError?.Invoke(this, new PlcEventArgs { 
                            Message = $"SendThread内部循环异常: {innerEx.Message}", 
                            Exception = innerEx 
                        });
                        Thread.Sleep(1000);
                    }
                }
            }
            catch (Exception ex)
            {
                OnError?.Invoke(this, new PlcEventArgs { 
                    Message = $"SendThread外部异常: {ex.Message}", 
                    Exception = ex 
                });
            }
            
            OnMessage?.Invoke(this, new PlcEventArgs { Message = "SendThread 已退出" });
        }

        /// <summary>
        /// 处理单个数据包的发送
        /// </summary>
        private void ProcessDataPackage(DataPackage package)
        {
            try
            {
                package.SendTimes++;
                package.SendTime = DateTime.Now;
                
                OnMessage?.Invoke(this, new PlcEventArgs { 
                    Message = $"ProcessDataPackage：准备发送CommandId={package.CommandId}" 
                });
                
                // 发送数据
                communication.Send(package);
                OnSend?.Invoke(this, package);
                
                OnMessage?.Invoke(this, new PlcEventArgs { 
                    Message = $"数据包 {package.CommandId} 已发送完成" 
                });
            }
            catch (Exception ex)
            {
                OnError?.Invoke(this, new PlcEventArgs { 
                    Message = $"发送数据包 {package.CommandId} 异常: {ex.Message}", 
                    Exception = ex 
                });
            }
        }

        public override IPlcResult Write(Command command, int data)
        {
            IPlcResult plcResult = new OrmonResult
            {
                Command = command
            };
            DataPackage package = new DataPackage();
            package.NeedLength = 30 + command.Length * 2; // 需要的长度，一个字代表2个字节，一个字节代表8位
            package.CommandId = GetCommandId(); // 设置命令ID

            package.SendBuffer = command.GetWriteBuffer(this.net, package.CommandId, data); // 获取写入数据的缓冲区
            Enqueue(package); // 将数据包添加到发送队列
            // 等待回复
            Stopwatch stopwatch = Stopwatch.StartNew();
            DataPackage receivedPackage = default; // 初始化变量
            bool found = false;
            while (stopwatch.ElapsedMilliseconds < net.MaxMilliseconds)
            {
                lock (receiveLocker)
                {
                    var foundPackage = receivePackages.Find(p => p.CommandId == package.CommandId);
                    if (foundPackage.CommandId != 0) // 找到匹配的包
                    {
                        receivedPackage = foundPackage; // 获取接收到的数据包
                        receivePackages.Remove(foundPackage); // 从接收队列中移除已处理的数据包
                        found = true;
                        break;
                    }
                }
                Task.Delay(50).Wait();
            }
            if (found)
            {
                CombineResult(plcResult, package, receivedPackage);
            }
            else
            {
                plcResult.Sucess = false;
                plcResult.Message = "写入超时，未收到PLC响应";
            }
            if (plcResult.Sucess)
            {
                plcResult.Message = "写入成功";
                OnMessage?.Invoke(this, new PlcEventArgs { Message = plcResult.Message });
            }
            else
            {
                plcResult.Message = "写入失败";
                OnError?.Invoke(this, new PlcEventArgs { Message = plcResult.Message });
            }
            OnReceived?.Invoke(this, new DataPackage { ReceiveBuffer = plcResult.ReceiveBuffer, ReceiveTime = DateTime.Now, CommandId = package.CommandId });
            WriteLog(command, package, plcResult);
            return plcResult;
        }

        public override async Task<IPlcResult> WriteAsync(Command command,int data)
        {
            return await Task.Run(() =>
            {
                return Write(command, data); // 直接调用同步版本
            });
        }

        // 在 OrmonPlc.cs 中添加诊断方法
        private void DiagnosticCheck()
        {
            var diagnostic = new
            {
                ConnectedState = connectedState,
                TcpConnected = communication.tcpClient?.Connected ?? false,
                SendQueueCount = sendPackages.Count,
                ReceiveListCount = receivePackages.Count,
                CancellationRequested = cancellationTokenSource.IsCancellationRequested
            };
            
            OnMessage?.Invoke(this, new PlcEventArgs { 
                Message = $"诊断信息: {JsonConvert.SerializeObject(diagnostic)}" 
            });
        }

        public override IPlcResult Write(Command command, List<int> data)
        {
            //下发指令
            OrmonResult plcResult = new OrmonResult
            {
                Command = command
            };
            DataPackage package = new DataPackage
            {
                CommandId = commandId++, // 设置命令ID
                NeedLength = 30 + command.Length * 2 // 需要的长度，一个字代表2个字节，一个字节代表8位
            };
            package.SendBuffer = command.GetWriteBuffer(this.net, package.CommandId, data); // 获取写入数据的缓冲区
            Enqueue(package); // 将数据包添加到发送队列
            // 等待回复
            Stopwatch stopwatch = Stopwatch.StartNew();
            DataPackage receivedPackage = default; // 初始化变量
            bool found = false;
            while (stopwatch.ElapsedMilliseconds < net.MaxMilliseconds)
            {
                lock (receiveLocker)
                {
                    var foundPackage = receivePackages.Find(p => p.CommandId == package.CommandId);
                    if (foundPackage.CommandId != 0) // 找到匹配的包
                    {
                        receivedPackage = foundPackage; // 获取接收到的数据包
                        receivePackages.Remove(foundPackage); // 从接收队列中移除已处理的数据包
                        found = true;
                        break;
                    }
                }
                Task.Delay(50).Wait();
            }
            if (found)
            {
                CombineResult(plcResult, package, receivedPackage);
            }
            else
            {
                plcResult.Sucess = false;
                plcResult.Message = "写入超时，未收到PLC响应";
            }
            if (plcResult.Sucess)
            {
                plcResult.Message = "写入成功";
                OnMessage?.Invoke(this, new PlcEventArgs { Message = plcResult.Message });
            }
            else
            {
                plcResult.Message = "写入失败";
                OnError?.Invoke(this, new PlcEventArgs { Message = plcResult.Message });
            }
            OnReceived?.Invoke(this, new DataPackage { ReceiveBuffer = plcResult.ReceiveBuffer, ReceiveTime = DateTime.Now, CommandId = package.CommandId });
            WriteLog(command, package, plcResult);
            return plcResult;

        }

        public override async Task<IPlcResult> WriteAsync(Command command, List<int> data)
        {
            return await Task.Run(() =>
            {
                return Write(command, data); // 直接调用同步版本
            });
        }

        /// <summary>
        /// 先获取数据类型，根据不同的类型将数据转换成不同的byte数组，
        /// 发送读取指令，等待并匹配响应数据包，最终返回带有原始字节流的泛型结果对象。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="command"></param>
        /// <returns></returns>
        public override IPlcResult<T> Read<T>(Command command)
        {
            OrmonResult<T> result = new OrmonResult<T>
            {
                Command = command
            };
            DataPackage package = new DataPackage();
            package.NeedLength = GetNeedLength<T>(command.Length); // 计算需要的长度
            package.CommandId = GetCommandId(); // 设置命令ID
            package.SendBuffer = command.GetReadBuffer(this.net, package.CommandId);// 生成读取指令的字节流
            Enqueue(package); // 将数据包添加到发送队列
            // 等待回复
            Stopwatch stopwatch = Stopwatch.StartNew();
            DataPackage receivedPackage = new DataPackage();
            while (stopwatch.ElapsedMilliseconds < net.MaxMilliseconds)
            {
                lock(receiveLocker)
                {
                    receivedPackage = receivePackages.Find(p => p.CommandId == package.CommandId);
                    if (receivedPackage.CommandId != 0) // 找到匹配的包
                    {
                        receivePackages.Remove(receivedPackage); // 从接收队列中移除已处理的数据包
                        break;
                    }
                }
                Thread.Sleep(10); // 等待10毫秒再检查
            }
            if(receivedPackage.ReceiveBuffer != null)
            {
                CombineResult(result, package, receivedPackage);
            }

            WriteLog(command, package, result);
            return result;
        }

      

        public override async Task<IPlcResult<T>> ReadAsync<T>(Command command)
        {
            return await Task.Run(() =>
            {
                return Read<T>(command); // 直接调用同步版本
            });
        }
        /// <summary>
        /// 先获取数据类型，根据不同的类型将数据转换成不同的byte数组，
        /// 拼接到command.sendbuffer，下发到communication层
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="command"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public override IPlcResult<T> Write<T>(Command command, T data)
        {
            //返回对象
            OrmonResult<T> plcResult = new OrmonResult<T>
            {
                Command = command
            };
            //创建数据包
            DataPackage package = new DataPackage();
            package.NeedLength = GetNeedLength<T>(command.Length); // 需要的长度
            package.CommandId = GetCommandId(); // 设置命令ID
            package.SendBuffer = command.GetWriteBuffer(this.net, package.CommandId, data); // 生成写入指令的字节流
            Enqueue(package); // 将数据包添加到发送队列
            // 等待回复
            Stopwatch stopwatch = Stopwatch.StartNew();
            DataPackage receive = new DataPackage();
            if (package.SendBuffer != null && package.SendBuffer.Length >0)
            {
                while (stopwatch.ElapsedMilliseconds < net.MaxMilliseconds)
                {
                    lock (receiveLocker)
                    {
                        receive = receivePackages.Find(p => p.CommandId == package.CommandId);
                        if (receive.CommandId > 0) // 找到匹配的包
                        {
                            receivePackages.Remove(receive); // 从接收队列中移除已处理的数据包
                            break;
                        }
                    }
                    Thread.Sleep(10); // 等待10毫秒再检查
                }
                if (receive.CommandId > 0)
                {
                    CombineResult(plcResult, package, receive);
                }
                else
                {
                    plcResult.Sucess = false;
                    plcResult.Message = "下发指令数据为空";
                    OnError?.Invoke(this, new PlcEventArgs { Message = plcResult.Message });
                }
                
                OnReceived?.Invoke(this, new DataPackage { ReceiveBuffer = plcResult.ReceiveBuffer, ReceiveTime = DateTime.Now, CommandId = package.CommandId });
            }

            return plcResult;
        }

       

        public override async Task<IPlcResult<T>> WriteAsync<T>(Command command, T data)
        {
            return await Task.Run(() =>
            {
                return Write<T>(command, data); // 直接调用同步版本
            });
        }

        public override void Stop()
        {
            base.Stop();
            //将来还是有一些需要在欧姆龙PLC停止时处理的逻辑
        }
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="length">字的长度</param>
        /// <returns></returns>
        private int GetNeedLength<T>(int length)
        {
            int result = 30;
            Type type = typeof(T);
            switch (type.FullName)
            {
                case "System.Int32":
                    result += length * 2;
                    break;
                case "System.UInt32":
                    result += length * 2;
                    break;
                case "System.Int16":
                    result += length * 2;
                    break;
                case "System.UInt16":
                    result += length * 2;
                    break;

                case "System.Int32[]":
                    result += length * 2;
                    break;
                case "System.UInt32[]":
                    result += length * 2;
                    break;
                case "System.Int16[]":
                    result += length * 2;
                    break;
                case "System.UInt16[]":
                    result += length * 2;
                    break;
                default:
                    result += length * 2; // 默认处理为字节
                    break;
            }
            return result;
        }
        /// <summary>
        /// 写入数据包日志
        /// </summary>
        /// <param name="command"></param>
        /// <param name="package"></param>
        /// <param name="result"></param>
        /// <exception cref="NotImplementedException"></exception>
        private void WriteLog(Command command, DataPackage package, IPlcResult result)
        {
            if (result == null) return;
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.Append($"序号: {package.CommandId}, 发送事件: {package.SendTime}, 回复时间: {package.ReceiveTime}, 耗时: {(package.EndTime - package.CreateTime).TotalMilliseconds}毫秒\r");
            stringBuilder.Append($"发送数据: {package.SendBufferToString}\r");
            stringBuilder.Append($"接收数据: {package.ReceiveBufferToString}\r");
            Log.Info(stringBuilder.ToString());//写入日志
        }

        private void WriteLog<T>(Command command, DataPackage package, OrmonResult<T> result)
        {
             WriteLog(command, package, (IPlcResult)result);
        }

        private static DataPackage CombineResult(IPlcResult result,DataPackage package,DataPackage receive)
        {
            if (receive.ReceiveBuffer != null)
            {
                package.SendTime = receive.SendTime;
                package.ReceiveTime = receive.ReceiveTime;
                package.ReceiveBuffer = receive.ReceiveBuffer;
                result.ReceiveBuffer = receive.ReceiveBuffer;
                result.Sucess = true;

            }

            return package;
        }
        private void CombineResult<T>(OrmonResult<T> plcResult, DataPackage package, DataPackage receive)
        {
             CombineResult((IPlcResult)plcResult, package, receive);
        }

           
    }
}
